package org.erepublik.company.scanner;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;

import org.erepublik.company.ECountry;
import org.erepublik.company.EProductType;
import org.erepublik.company.comparators.FoodComparatorByWellness;
import org.erepublik.company.product.EProductAttribute;
import org.erepublik.company.product.Food;
import org.erepublik.company.product.ProductDesign;
import org.erepublik.company.product.ProductKey;
import org.erepublik.company.service.ICompanyCountryService;
import org.erepublik.company.service.IVatService;
import org.erepublik.company.service.JSONExchangeRateService;

/**
 * Klasa sluzaca do pozyskania listy produktow z internetu.
 * 
 * 
 * @author Kacper Gorski 'Railman' railman85@gmail.com
 */
public class FoodScanner extends ProductScanner<Food> {

    @Override
    protected Food[] getEmptyTable() {
        return new Food[0];
    }

    @Override
    protected Food getNewProduct() {
        return new Food();
    }

    
    @Override
    public Food[] getProductsFromCountry(ECountry country, IVatService vatService, ICompanyCountryService companyService,
            JSONExchangeRateService currency) throws Exception {
        ProductDesign productDesign = new ProductDesign(EProductType.FOOD);
        HashMap<ProductKey, Food> map = new HashMap<ProductKey, Food>();

        ArrayList<CutValue> bottomCutValue = new ArrayList<CutValue>();
        ArrayList<CutValue> topCutValue = new ArrayList<CutValue>();
        for (int i = 0; i <= 100; i += 10) {
            int j=0;
                if (!isWorthChecking(i, j, bottomCutValue, topCutValue)) {
                    continue;
                }
                productDesign.setAttributeValue(EProductAttribute.WELLNESS, i);
                productDesign.setAttributeValue(EProductAttribute.HAPPINESS, j);
                Food[] scannedProducts = getProductList(country, productDesign, vatService, companyService, currency);
                CutValue topCut = getMinimalAttributes(scannedProducts);
                topCutValue.add(topCut);
                if (scannedProducts.length < 10)
                    bottomCutValue.add(new CutValue(i, j));
                for (Food product : scannedProducts) {
                    ProductKey key = new ProductKey(product.getCompanyOwner().getId(), country);
                    if (!map.containsKey(product)) {
                        map.put(key, product);
                    }
                }
            
        }
        Food[] products = map.values().toArray(new Food[0]);
        Arrays.sort(products, new FoodComparatorByWellness());
        return products;
    }

    private CutValue getMinimalAttributes(Food[] scannedProducts) {
        int minWell=100;
        int minHapp=100;
        for (int i=0; i < scannedProducts.length; i++) {
            if (minWell > scannedProducts[i].getProductDesign().getAttributeValue(EProductAttribute.WELLNESS))
                minWell = scannedProducts[i].getProductDesign().getAttributeValue(EProductAttribute.WELLNESS);
            if (minHapp > scannedProducts[i].getProductDesign().getAttributeValue(EProductAttribute.HAPPINESS))
                minHapp = scannedProducts[i].getProductDesign().getAttributeValue(EProductAttribute.HAPPINESS);
        }
        return new CutValue(minWell, minHapp);
    }

    private boolean isWorthChecking(int i, int j, ArrayList<CutValue> cutValues, ArrayList<CutValue> topCutValue) {
        
        
        
        for (CutValue cutValue : cutValues) {
            if (j >= cutValue.getHeppinessCutValue() && i >= cutValue.getWellnessCutValue()) {
                return false;
            }
        }
        for (CutValue cutValue : topCutValue) {
            if (j <= cutValue.getHeppinessCutValue() && i <= cutValue.getWellnessCutValue()) {
                return false;
            }
        }
        return true;
    }



}


class CutValue {
    private int wellnessCutValue = 0;
    private int heppinessCutValue = 0;

    public CutValue(int wellnessCutValue, int heppinessCutValue) {
        this.wellnessCutValue = wellnessCutValue;
        this.heppinessCutValue = heppinessCutValue;
    }

    public int getWellnessCutValue() {
        return wellnessCutValue;
    }

    public int getHeppinessCutValue() {
        return heppinessCutValue;
    }
}